`
https://leetcode.cn/problems/replace-the-substring-for-balanced-string/
`

/**
 * @param {string} s
 * @return {number}
 */
var balancedString = function (s) {
  const n = s.length
  const m = Math.floor(n / 4)

  // counter 统计的是窗口外面的字符数
  const { get, set, minCount, maxCount } = counter()
  for (const c of s) {
    set(c, get(c) + 1)
  }
  if (minCount() === m) return 0

  let res = n
  let left = 0, right = 0

  while (right < n) {
    const c = s[right++]
    set(c, get(c) - 1)

    // 窗口之外的任意字母的个数都不超过 m 就是一个解
    // 因为此时能够随意替换窗口内的字母使字符串平衡
    while (maxCount() <= m) {
      res = Math.min(res, right - left)
      const d = s[left++]
      set(d, get(d) + 1)
    }
  }

  return res
};

const map = { Q: 0, W: 1, E: 2, R: 3 }

function counter() {
  const cnt = new Array(4).fill(0)
  return {
    get(c) {
      return cnt[map[c]]
    },
    set(c, val) {
      cnt[map[c]] = val
    },
    minCount() {
      return Math.min(...cnt)
    },
    maxCount() {
      return Math.max(...cnt)
    }
  }
}
